package com.study.springmvc.servlet;

import com.study.springmvc.anno.Controller;
import com.study.springmvc.anno.RequestMapping;
import com.study.springmvc.anno.Security;
import com.study.springmvc.context.BeanFactory;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import org.reflections.Reflections;

/**
 * @author lupengwei 2021/5/17 18:20
 */
public class SecurityMappingResolver {
    
    private Map<String, String[]> securityMapping;
    
    
    public SecurityMappingResolver(BeanFactory beanFactory, Properties properties) {
        init(beanFactory, properties);
    }
    
    
    private void init(BeanFactory beanFactory, Properties properties) {
        String scanPackage = properties.getProperty("spring.scan.package");
        Reflections reflections = new Reflections(scanPackage);
    
        securityMapping = new HashMap<>(16);
        Set<Class<?>> classSet = reflections.getTypesAnnotatedWith(Controller.class);
        for (Class<?> aClass : classSet) {
            // 只有同时添加了 @RequestMapping 和 @Security 注解的才会校验权限
            Method[] methods = aClass.getMethods();
            for (Method method : methods) {
                RequestMapping annotation = method.getAnnotation(RequestMapping.class);
                Security securityAnnotation = method.getAnnotation(Security.class);
                if (annotation == null || securityAnnotation == null) {
                    continue;
                }
            
                // URL
                String url = annotation.value();
    
                // 用户权限
                String[] userArr = securityAnnotation.value();
                
                // 建立 URL 和 用户权限的映射关系
                securityMapping.put(url, userArr);
            }
        }
    }
    
    public boolean verifyPermission(String url, String username) {
        String[] userArr = securityMapping.get(url);
        if (userArr == null) {
            return true;
        }
    
        for (String user : userArr) {
            if (username.equals(user)) {
                return true;
            }
        }
        return false;
    }
}
